import { RandomManager } from "db://oops-framework/core/common/random/RandomManager";
import { RoleAttributeType, RoleModuleType } from "../../../../role/model/RoleEnum";
import { Role } from "../../../../role/Role";
import { EffectDamage } from "../../model/report/EffectDamage";
import { ISkillReport } from "../../model/report/ISkillReport";
import { BattleEventTrigger } from "./BattleEventTrigger";
import { BattleDamageType, BattleRoleState } from "../../../scene/model/BattleEnum";
import { RoleDamageNormal } from "./RoleDamageNormal";
import { RoleDamageSkill } from "./RoleDamageSkill";
import { smc } from "../../../../common/ecs/SingletonModuleComp";
import { BattleType } from "../../../scene/SceneEvent";
import { RoleState } from "./RoleState";
import { RoleAttribute } from "./RoleAttribute";

/** 角色伤害计算 */
export class RoleDamage {
    /**
   * 减去防御属性后的伤害
   * @param sr        技能施放战报
   * @param target    受击目标
   */
    static normal(isr: ISkillReport, target: Role) {
        var effect = new EffectDamage();
        // 战斗事件：技能效果计算前
        BattleEventTrigger.onCastBefore(isr, target, effect);

        // 战斗事件：受击前
        BattleEventTrigger.onHitBefore(isr, target, effect);

        // 目标防御值与技能释放者攻击值计算伤害值
        this.calculateDamage(isr, target, effect);

        // 目标身上的护盾抵御伤害计算
        this.calculateDamageShield(isr, target, effect);

        // 目标最终伤害值扣除
        this.setDamage(isr, target, effect);

        //加怒气
        this.addPower(isr, target);

        // 验证目标死亡流程

        // 验证技能施放者死亡流程（可能反伤死）

        // 战斗事件：受击后（目标死亡则没有受击后流程，直接进入死亡流程）
        BattleEventTrigger.onHitAfter(isr, target, effect);

        // 战斗事件：技能效果计算后（施放者死亡则没有施放后流程，直接进入死亡流程）
        BattleEventTrigger.onCastAfter(isr, target, effect);

        return effect;
    }


    /** 目标防御值与技能释放者攻击值计算伤害值 */
    private static calculateDamage(isr: ISkillReport, target: Role, effect: EffectDamage) {
        var caster = isr.caster;
        var damage: number = 0;
        var isCritical: boolean = false;
        var isBlock: boolean = false;

        //普攻伤害
        if (isr.skill.SkillModel.table.skill_type == 1) {
            damage = RoleDamageNormal.getDamage(isr, target);
        }
        //技能伤害
        else if (isr.skill.SkillModel.table.skill_type == 2) {
            damage = RoleDamageSkill.getDamage(isr, target);
        }

        if (caster) {
            //暴击
            var bj = caster.getNumericValue(RoleAttributeType.bj);
            var bjdk = target.getNumericValue(RoleAttributeType.bjdk);
            var bs = caster.getNumericValue(RoleAttributeType.bs);
            var bsdk = target.getNumericValue(RoleAttributeType.bsdk);
            //我暴击概率：我暴击-敌暴击抵抗，最大值100%（必暴击），最小值0%（必不暴击）
            if (RandomManager.instance.isBingo(bj - bjdk)) {
                isCritical = true;
                //我暴击伤害=我的伤害*（1+我暴伤-敌暴伤抵抗）
                //注：我的伤害即普攻伤害或技能伤害；1+我暴伤-敌暴伤抵抗强制≥1.5
                damage = Math.round(damage * Math.min((1 + bs - bsdk), 1.5));
            }

            //格挡
            var jz = caster.getNumericValue(RoleAttributeType.jz);
            var gd = target.getNumericValue(RoleAttributeType.gd);
            //敌格挡概率：敌格挡-我精准，最大值100%（必格挡），最小值0%（必不格挡）
            if (RandomManager.instance.isBingo(gd - jz)) {
                isBlock = true;
                //敌格挡所受伤害 = 我的最终伤害 * 67%
                //注：我的最终伤害即普攻或技能计算完暴击之后的伤害
                damage = Math.round(damage * 0.67);

                BattleEventTrigger.onBlock(isr, target, effect);
            }
        }

        // 如果目标有特殊的防御效果（比如免疫物理攻击），则在这里进行处理

        // 将计算出的伤害值保存到effect对象中
        effect.damage = damage;
        effect.value = -damage;
        if (isBlock) {
            effect.hitEffect = BattleDamageType.Block;
        } else if (isCritical) {
            effect.hitEffect = BattleDamageType.Critical;
        }
    }
    /** 目标身上的护盾抵御伤害计算 */
    private static calculateDamageShield(isr: ISkillReport, target: Role, effect: EffectDamage) {
        // 获取目标身上的护盾值
        var shield = target.getNumericValue(RoleAttributeType.shield);
        if (shield > 0) {
            // 如果有护盾，则先扣除护盾值
            if (shield >= effect.damage) {
                // 护盾足够强，完全抵消伤害
                shield -= effect.damage;
                effect.shieldDamage = effect.damage;
                effect.damage = 0;
            } else {
                // 护盾不够强，只能抵消部分伤害
                effect.shieldDamage = shield;
                effect.damage -= shield;
                shield = 0;
            }

            // 更新目标身上的护盾值
            target.setNumericValue(RoleAttributeType.shield, RoleModuleType.Decorator, shield);

            // 触发护盾破裂事件（如果护盾被完全破裂）
            if (shield == 0) {
                target.removeShield();
                BattleEventTrigger.onFriendShieldOver(target);
            }
        }
    }

    /** 设置伤害 */
    static setDamage(isr: ISkillReport, target: Role, effect: EffectDamage, caster: Role = null!) {
        var target_hp = target.getNumericValue(RoleAttributeType.hp_battle);
        var damage = effect.damage;
        var value = -effect.value;

        var hp_new = target_hp - damage;
        if (hp_new <= 0) {
            hp_new = 0;
            effect.state = BattleRoleState.Die
        }
        else {
            effect.state = BattleRoleState.Alive
        }

        // 扣血
        target.setNumericValue(RoleAttributeType.hp_battle, RoleModuleType.Battle, hp_new);

        if (target.RoleModel.battleType == BattleType.Scene) {
            if (!target.RoleModel.myTeam) {
                smc.scene.setEnemysTotalHp(2);
            }
        } else if (target.RoleModel.battleType == BattleType.Boss) {
            // if(!target.RoleModel.myTeam){
            //     smc.boss.bossDamage(value, hp_new);
            //     effect.state = BattleRoleState.Alive;
            // }
        } else if (target.RoleModel.battleType == BattleType.Tower) {
            // var casterUuid: string = caster ? caster!.RoleModel.uuid as string : isr.caster!.RoleModel.uuid as string;
            // var shuchu = smc.tower.TowerBattleModel.shuchu.get(casterUuid) || 0;
            // shuchu += value;
            // smc.tower.TowerBattleModel.shuchu.set(casterUuid, shuchu);

            // var targetUuid: string = target.RoleModel.uuid as string;
            // var chengshang = smc.tower.TowerBattleModel.chengshang.get(targetUuid) || 0;
            // chengshang += value;

            // smc.tower.TowerBattleModel.chengshang.set(targetUuid, chengshang);

            // smc.tower.setTotalHp(2);
        }
        // 战报：伤害受击
        isr.sc?.hit(target, effect);

        // 战斗事件：死亡前触发
        if (RoleState.isDie(target)) {
            if (!target.RoleModel.myTeam && target.RoleModel.battleType == BattleType.Boss) {
                return
            }
            RoleState.checkBattleResult(target.RoleModel.battleType)
        }
    }


    /** 当被武将普通攻击一次加10（敌我双发武将均是），当被武将技能攻击一次加15，
     * 当被boss普通攻击一次加10，当被boss技能攻击一次加15
     * */
    private static addPower(isr: ISkillReport, target: Role) {
        var caster = isr.caster;
        var skillType = isr.skill.SkillModel.table.skill_type;
        if (!caster) {
            return
        }

        var casterType = caster.RoleModel.table.type;
        var targetType = target.RoleModel.table.type;

        if (casterType == 2 || casterType == 4 || casterType == 6) {
            //被武将，boss，神兽攻击
            if (skillType == 1) {
                //普通攻击
                if (targetType == 2 || targetType == 4) {
                    //被击者是武将，boss
                    RoleAttribute.add(target, RoleAttributeType.power, 10);
                } else if (targetType == 6) {
                    //被击者是神兽
                    RoleAttribute.add(target, RoleAttributeType.power, 10);
                    //  smc.boss.BossBattleModel.vm.bossPower += 10;
                }
            } else if (skillType == 2) {
                //技能攻击
                if (targetType == 2 || targetType == 4) {
                    RoleAttribute.add(target, RoleAttributeType.power, 15);
                } else if (targetType == 6) {
                    RoleAttribute.add(target, RoleAttributeType.power, 15);
                    // smc.boss.BossBattleModel.vm.bossPower += 15;
                }
            }
        }
    }
}